package com.zackeus.mvvm.widget.zxing;

import android.content.Context;
import android.util.AttributeSet;

import com.journeyapps.barcodescanner.ViewfinderView;

import android.annotation.SuppressLint;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Rect;
import android.graphics.Shader;
import android.util.TypedValue;

import androidx.core.content.ContextCompat;

import com.google.zxing.ResultPoint;
import com.zackeus.mvvm.R;

import java.util.List;

/**
 * 扫描框(线条滚动 二维码边角)
 * @name: CommonViewFinderView
 * @author: zz
 * @date: 2022/9/30
 */
public class CommonViewFinderView extends ViewfinderView {

    /* 重绘时间间隔 */
    protected static long ANIMATION_DELAY = 16;

    /* 边角线颜色 */
    protected int mLineColor = ContextCompat.getColor(getContext(), R.color.green2);
    /* 边角线厚度 (建议使用dp) */
    protected float mLineDepth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2f, getResources().getDisplayMetrics());
    /* "边角线长度/扫描边框长度"的占比 (比例越大，线越长) */
    protected float mLineRate = 0.05f;
    /* 扫描线起始位置 */
    protected int mScanLinePosition = 0;
    /* 扫描线每次重绘的移动距离 */
    protected float mScanLineDy = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3f, getResources().getDisplayMetrics());

    /* 线性梯度 */
    protected LinearGradient mLinearGradient;
    /* 线性梯度位置 */
    protected float[] mPositions = {0f, 0.5f, 1f};

    /* 扫描线厚度 */
    protected float mScanLineDepth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1f, getResources().getDisplayMetrics());
    //扫描线渐变色
    protected int laserColor_center = ContextCompat.getColor(getContext(), R.color.green2);

    protected int laserColor_light = ContextCompat.getColor(getContext(), R.color.green2);

    protected int[] mScanLineColor = {laserColor_light, laserColor_center, laserColor_light};

    public CommonViewFinderView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @SuppressLint("DrawAllocation")
    @Override
    public void onDraw(Canvas canvas) {
        refreshSizes();
        if (framingRect == null || previewSize == null) {
            return;
        }
        Rect frame = framingRect;
        int width = getWidth();
        int height = getHeight();

        // Draw the exterior (i.e. outside the framing rect) darkened
        paint.setColor(resultBitmap != null ? resultColor : maskColor);
        canvas.drawRect(0f, 0f, width, frame.top, paint);
        canvas.drawRect(0f, frame.top, frame.left, (frame.bottom + 1), paint);
        canvas.drawRect((frame.right + 1), frame.top, width, (frame.bottom + 1), paint);
        canvas.drawRect(0f, (frame.bottom + 1), width, height, paint);

        /* 绘制4个角 */
        paint.setColor(mLineColor);

        // 定义画笔的颜色
        //左上-横线
        canvas.drawRect(frame.left - mLineDepth,
                frame.top - mLineDepth,
                frame.left + frame.width() * mLineRate,
                frame.top, paint);
        //左上-纵线
        canvas.drawRect(frame.left - mLineDepth, frame.top, frame.left, frame.top + frame.height() * mLineRate, paint);
        //右上-横线
        canvas.drawRect(frame.right - frame.width() * mLineRate, frame.top - mLineDepth, frame.right + mLineDepth, frame.top, paint);
        //右上-纵线
        canvas.drawRect(frame.right, frame.top - mLineDepth, frame.right + mLineDepth, frame.top + frame.height() * mLineRate, paint);
        //左下-横线
        canvas.drawRect(frame.left - mLineDepth, frame.bottom, frame.left + frame.width() * mLineRate, frame.bottom + mLineDepth, paint);
        //左下-纵线
        canvas.drawRect(frame.left - mLineDepth, frame.bottom - frame.height() * mLineRate, frame.left, frame.bottom, paint);
        //右下-横线
        canvas.drawRect(frame.right - frame.width() * mLineRate, frame.bottom, frame.right + mLineDepth, frame.bottom + mLineDepth, paint);
        //右下-纵线
        canvas.drawRect(frame.right, frame.bottom - frame.height() * mLineRate, frame.right + mLineDepth, frame.bottom + mLineDepth, paint);
        if (resultBitmap != null) {
            paint.setAlpha(ViewfinderView.CURRENT_POINT_OPACITY);
            canvas.drawBitmap(resultBitmap, null, frame, paint);
        } else {
            /* 绘制扫描线 start */
            mScanLinePosition += mScanLineDy;
            if (mScanLinePosition > frame.height()) {
                mScanLinePosition = 0;
            }

            mLinearGradient = new LinearGradient(frame.left, (frame.top + mScanLinePosition), frame.right, (frame.top + mScanLinePosition), mScanLineColor, mPositions, Shader.TileMode.CLAMP);
            paint.setShader(mLinearGradient);
            canvas.drawRect(frame.left, (frame.top + mScanLinePosition), frame.right, frame.top + mScanLinePosition + mScanLineDepth, paint);
            paint.setShader(null);
            /* 绘制扫描线 end */

            /* 绘制扫描点 start */
            final float scaleX = this.getWidth() / (float) previewSize.width;
            final float scaleY = this.getHeight() / (float) previewSize.height;

            // draw the last possible result points
            if (!lastPossibleResultPoints.isEmpty()) {
                paint.setAlpha(CURRENT_POINT_OPACITY / 2);
                paint.setColor(resultPointColor);
                float radius = POINT_SIZE / 2.0f;
                for (final ResultPoint point : lastPossibleResultPoints) {
                    canvas.drawCircle(
                            (int) (point.getX() * scaleX),
                            (int) (point.getY() * scaleY),
                            radius, paint
                    );
                }
                lastPossibleResultPoints.clear();
            }

            // draw current possible result points
            if (!possibleResultPoints.isEmpty()) {
                paint.setAlpha(CURRENT_POINT_OPACITY);
                paint.setColor(resultPointColor);
                for (final ResultPoint point : possibleResultPoints) {
                    canvas.drawCircle(
                            (int) (point.getX() * scaleX),
                            (int) (point.getY() * scaleY),
                            POINT_SIZE, paint
                    );
                }

                // swap and clear buffers
                final List<ResultPoint> temp = possibleResultPoints;
                possibleResultPoints = lastPossibleResultPoints;
                lastPossibleResultPoints = temp;
                possibleResultPoints.clear();
            }
            /* 绘制扫描点 end */

        }
        postInvalidateDelayed(ANIMATION_DELAY, frame.left, frame.top, frame.right, frame.bottom);
    }
}
